//////////////////////////////////////////////////////////////////////////
//	Name: CDXShaderManader.cpp
//	Purpose: Loads and maintains the shaders for the program
//	Created: October 21, 2009
//////////////////////////////////////////////////////////////////////////

#include "CDXShaderManager.h"
#include "CDXRenderWin32.h"
#include "CDXTextureManager.h"

#include <assert.h>

CDXShaderManader::CDXShaderManader()
{

};

CDXShaderManader::~CDXShaderManader()
{

};

bool CDXShaderManader::LoadShadersFromDirectory()
{

	vector<string> vShaderNames;		
	string strFileExtension = "fx";	//TODO: Change this to the extension you want.
	char szString[MAX_PATH];

	char szCurrWorkDir[MAX_PATH];
	_getcwd(szCurrWorkDir,MAX_PATH);
	string strFileLocation;
	strFileLocation.append(szCurrWorkDir);
	strFileLocation.append("\\Shaders");

	SearchDirectory(vShaderNames, strFileLocation, strFileExtension);	
	if(vShaderNames.size() != 0)
	{		
		for(unsigned int i = 0; i < vShaderNames.size();++i)
		{
			string strFileToAdd; // = strFileLocation + "\\" + vShaderNames[SongAmount];

			sprintf_s(szString, MAX_PATH, "%s%s%s", strFileLocation.c_str(), "\\", vShaderNames[i].c_str());
			strFileToAdd = szString;

			//////////////////////////////////////////////////////////////////////////
			//TODO! Load the shaders here!!!
			//////////////////////////////////////////////////////////////////////////
			DXSHADER theShader;
			theShader.szEffectName = vShaderNames[i];
			//and then check the result.. or you could just do
			if(FAILED(D3DXCreateEffectFromFile((m_DXR->GetDevice()),strFileToAdd.c_str(),NULL,NULL,0,NULL,&theShader.theEffect,NULL)))
			{
				MessageBox(NULL,"ERROR!!","SHADER FAIL!!",MB_OK);
			}
// 			if(FAILED(m_DXR->GetInstance()->DXCreateEffectFromFile(*(m_DXR->GetDevice()),strFileToAdd.c_str(),NULL,NULL,0,NULL,&theShader.theEffect,NULL)))
// 			{
// 				MessageBox(NULL,"ERROR!!","SHADER FAIL!!",MB_OK);
// 			}

			theShader.theEffect->FindNextValidTechnique(NULL,&theShader.hTech);
			m_vShaders.push_back(theShader);

		}
		vShaderNames.clear();
		//////////////////////////////////////////////////////////////////////////
		//We made it though all the shaders
		//////////////////////////////////////////////////////////////////////////
		return true;
	}
	else
	{
		return false;
	}
	
	//////////////////////////////////////////////////////////////////////////
	//Should never make it this far
	//////////////////////////////////////////////////////////////////////////
	return true;
}

bool CDXShaderManader::Init()
{
	m_DXR = CDXRenderWin32::GetInstance();

	return true; //Success
}

void CDXShaderManader::SearchDirectory(vector<string> &vListofFileName, string &strRootDirToLookIn, string &strExtToLookFor)
{
	string			szPattern;		//Pattern of FileNames to look for
	HANDLE			hFile;			//Handle to the file
	WIN32_FIND_DATA FileInfo;		//Holds file info - proves it's not a subfolder.
	char			szString[MAX_PATH];	// For some reason the "+" operator doesn't work for me and Sass.

	//Truncate a "\\*." and the extension we are looking for into the root directory
	//szPattern = strRootDirToLookIn + "\\*." + strExtToLookFor;
	sprintf_s(szString, MAX_PATH, "%s%s%s", strRootDirToLookIn.c_str(), "\\*.", strExtToLookFor.c_str());

	szPattern = szString;

	//Find the first file inside the folder that has proper extension
	hFile = FindFirstFile(szPattern.c_str(), &FileInfo);
	if(hFile != INVALID_HANDLE_VALUE)
	{
		do
		{//As long as it is a file and NOT a subfolder proceed with pushing of FileName into provided list
			if((FileInfo.cFileName[0] != '.') && (FileInfo.dwFileAttributes | FILE_ATTRIBUTE_DIRECTORY) )
			{
				vListofFileName.push_back(FileInfo.cFileName);
			}
			//Keep looping until there is NO more files in the folder
		} 
		while(FindNextFile(hFile, &FileInfo) == TRUE);
		// Close handle
		FindClose(hFile);
	}
	else
	{
		//MessageBox(CGame::GetInstance()->GetHWND(), (LPCTSTR)"Failed to find First File.\nhFile == INVALID_HANDLE_VALUE", (LPCTSTR)"Music Manager Failure", MB_OK);
	}

}
int CDXShaderManader::GetShaderIndex(string szShaderFileName)
{
	for(unsigned int i = 0; i < m_vShaders.size(); i++)
	{
		if (strcmp(m_vShaders[i].szEffectName.c_str(),szShaderFileName.c_str()) == 0)
		{
			return i;
		}
		else
		{
			continue;
		}
	}
	//NOT THERE!!!
	return -1;
}

DXSHADER* CDXShaderManader::GetDXShader(int nIndex)
{

	// Make sure the nID is in range.
	assert(nIndex > -1 && nIndex < (int)m_vShaders.size() && "nID is out of range");

	if (nIndex > (int)m_vShaders.size())
	{
		return NULL;
	}
	if (nIndex >= 0 && (int)m_vShaders.size() > nIndex)
	{
		return &m_vShaders[nIndex];
	}
	return NULL;
}

void CDXShaderManader::SetTexture(int nShaderID, int nTextureID, string szParameter)
{
	// Make sure the nID is in range.
	assert(nShaderID > -1 && nShaderID < (int)m_vShaders.size() && "nID is out of range");

	if (nShaderID > (int)m_vShaders.size())
	{
		return;
	}
	else
	{
		m_vShaders[nShaderID].theEffect->SetTexture(szParameter.c_str(),CDXTextureManager::GetInstance()->GetDXTextureData(nTextureID));
	}

}

void CDXShaderManader::SetMatrix(int nShaderID, string szParameter, CONST D3DXMATRIX* pMatrix)
{
	// Make sure the nID is in range.
	assert(nShaderID > -1 && nShaderID < (int)m_vShaders.size() && "nID is out of range");

	if (nShaderID > (int)m_vShaders.size())
	{
		return;
	}
	else
	{
		m_vShaders[nShaderID].theEffect->SetMatrix(szParameter.c_str(),pMatrix);
	}

} 

void CDXShaderManader::SetVector(int nShaderID, string szParameter, CONST D3DXVECTOR4* pVec)
{
	// Make sure the nID is in range.
	assert(nShaderID > -1 && nShaderID < (int)m_vShaders.size() && "nID is out of range");

	if (nShaderID > (int)m_vShaders.size())
	{
		return;
	}
	else
	{
		m_vShaders[nShaderID].theEffect->SetVector(szParameter.c_str(),pVec);
	}
}

void CDXShaderManader::SetFloat(int nShaderID, string szParameter, CONST float fFloat)
{
	// Make sure the nID is in range.
	assert(nShaderID > -1 && nShaderID < (int)m_vShaders.size() && "nID is out of range");

	if (nShaderID > (int)m_vShaders.size())
	{
		return;
	}
	else
	{
		m_vShaders[nShaderID].theEffect->SetFloat(szParameter.c_str(),fFloat);
	}
}

//EOF